package com.jeeplus.cms.config.freemarker.loader;

import com.jeeplus.modules.cms.template.entity.CmsTemplate;
import com.jeeplus.modules.cms.template.service.CmsTemplateService;
import freemarker.cache.TemplateLoader;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

/**
 * 数据库模板加载器
 *
 * @author Sawyer
 * @date 2020-12-21
 */
public class DatabaseTemplateLoader implements TemplateLoader {

    private CmsTemplateService templateService;


    public DatabaseTemplateLoader() {

    }

    public DatabaseTemplateLoader(CmsTemplateService templateService) {
        this.templateService = templateService;
    }

    @Override
    public Object findTemplateSource(String name) throws IOException {
        String templateId = StringUtils.trimToEmpty(name);
        if ("".equals(templateId)) {
            return null;
        }

        try {
            CmsTemplate dbTemplate = templateService.get(templateId);
            //数据库表必须有一个最后更新字段用来刷新缓存
            return new StringTemplateSource(templateId, dbTemplate.getContent(), dbTemplate.getUpdateDate().getTime());
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public long getLastModified(Object templateSource) {
        return ((StringTemplateSource) templateSource).lastModified;
    }

    @Override
    public Reader getReader(Object templateSource, String encoding) throws IOException {
        return new StringReader(((StringTemplateSource) templateSource).templateContent);
    }

    @Override
    public void closeTemplateSource(Object templateSource) throws IOException {

    }

    private static class StringTemplateSource {
        private final String name;
        private final String templateContent;
        private final long lastModified;

        StringTemplateSource(String name, String templateContent, long lastModified) {
            if (name == null) {
                throw new IllegalArgumentException("name == null");
            }
            if (templateContent == null) {
                throw new IllegalArgumentException("source == null");
            }
            if (lastModified < -1L) {
                throw new IllegalArgumentException("lastModified < -1L");
            }
            this.name = name;
            this.templateContent = templateContent;
            this.lastModified = lastModified;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + name.hashCode();
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            StringTemplateSource other = (StringTemplateSource) obj;
            return name.equals(other.name);
        }


        @Override
        public String toString() {
            return name;
        }

    }
}
